#include "Platform/Platform.h"

#include "GlobalClass.h"

#include <QPixmap>
#include <QPainter>
#include <QHash>


////////////////////////////////////////////////
long Random(long n1,long n2)
{
    if(n1==n2)return n1;
    else if(n2<n1)
    {
        n1=n1+n2;
        n2=n1-n2;
        n1=n1-n2;
    }
    return (qrand() % ( n2 - n1 )) + n1;
    //int value=minValue+int((maxValue-minValue)*(rand()/(float)RAND_MAX));
}
long RandTarget(int n, int m)        //    m分之n
{
    if(n > m || n < 0)return -1;    //不符合
    if(qrand() % m < n)return 1;    //命中
    return 0;
}

//n1到n2产生n个不同数字返回到arr

//使用hash
bool GetDifferentNumber(long n1, long n2, void *arr, int n, int elementSize)
{
    QHash<long,bool> hash;
    if(abs(n2 - n1) < n)
        return false;

    long number;
    for(int i = 0; i < n;)
    {
        number = Random(n1,n2);
        if(!hash.contains(number)) {
            hash[number] = true;
            memcpy((char*)arr + (i * elementSize), &number, elementSize);
            i++;
        }
    }
    return true;
}


//简单的对比
void GetDifferentNumber2(long n1, long n2, long arr[],int n)
{
    for(int i = 0; i < n; i++)
    {
        arr[i] = Random(n1,n2);
        for(int j = 0; j < i; j++)
        {
            if(arr[j] == arr[i])
            {
                i--;
                break;
            }
        }
    }
}




//以空间换时间
/*
arr :数组名
n  :给定的数组长度
转移数组中的数据
*/
void GetDifferentNumber5(int arr[],int n)
{
    int sn = n, index;
    int *pfrom = new int[sn];
    for(int i = 0; i < sn; i++)
        *(pfrom + i) = i + 1 ;    //设置pfrom数组为1~sn+1

    for(int k = 0;k < sn;)
    {
        index = rand() % sn;
        if(*(pfrom+index) != 0)
        {   //从源数据pfrom取，每取一个将其置为0，直至pfrom中所有元素都为0
            *(arr+k) = pfrom[index];
            pfrom[index] = 0;
            k++;
        }
    }
    delete[] pfrom;
}

void GetDifferentNumber6(int n,int arr[])
{
    int i,m;
    memset(arr,0,sizeof(int) * n);
    for(i = 1; i <= n; i++)    //将 1 ~ n 打乱并放入 arr 中
    {
        while(arr[m = rand() % n]);        //找到a[m]为0的
        arr[m]=i;
    }
}



int nonASCIICount(QString str)
{
    QTextCodec *codec = QTextCodec::codecForName("UTF-8");//GB18030 UTF-8
    return (codec->fromUnicode(str).length() - str.length()) / 2;
}

////////////////////////////////////////////////




#include <QTimer>
#include <QEventLoop>
#include <QCoreApplication>

//
void Wait(int msec, QEventLoop::ProcessEventsFlags flags = QEventLoop::AllEvents)
{
    QEventLoop eventloop;
    QTimer::singleShot(msec, &eventloop, SLOT(quit()));
    eventloop.exec(flags);
}


void Wait1(int msec)
{
    QTime dieTime = QTime::currentTime().addMSecs(msec);
    while(QTime::currentTime() < dieTime)
    {
        QCoreApplication::processEvents(QEventLoop::AllEvents, 100);    //手动派发事件
    }
}

#include <QElapsedTimer>
void Wait2(int msec)
{
    QElapsedTimer t;
    t.start();
    while(t.elapsed() < msec)
    {
        QCoreApplication::processEvents(QEventLoop::AllEvents, 100);    //手动派发事件
    }
}


////////////////////////////////////////////////





#include <QFileInfo>
#include <QDir>
#include <QMessageBox>

bool copyDirectoryFiles(const QString &fromDir, const QString &toDir, bool coverFileIfExist)
{
    QDir sourceDir(fromDir);
    QDir targetDir(toDir);
    if(!targetDir.exists()){    /**< 如果目标目录不存在，则进行创建 */
        if(!targetDir.mkdir(targetDir.absolutePath()))
            return false;
    }

    QFileInfoList fileInfoList = sourceDir.entryInfoList();
    foreach(QFileInfo fileInfo, fileInfoList){
        if(fileInfo.fileName() == "." || fileInfo.fileName() == "..")
            continue;

        if(fileInfo.isDir()){    /**< 当为目录时，递归的进行copy */
            if(!copyDirectoryFiles(fileInfo.filePath(),
                targetDir.filePath(fileInfo.fileName()),
                coverFileIfExist))
                return false;
        }
        else{            /**< 当允许覆盖操作时，将旧文件进行删除操作 */
            if(coverFileIfExist && targetDir.exists(fileInfo.fileName())){
                targetDir.remove(fileInfo.fileName());
            }

            /// 进行文件copy
            if(!QFile::copy(fileInfo.filePath(),
                targetDir.filePath(fileInfo.fileName()))){
                    return false;
            }
        }
    }
    return true;
}

bool copyFileAndSetPermissions(const QString& filename, QFileDevice::Permissions permissionSpec)
{
    QFileInfo fi(filename);
    //fi.setFile(filename);
    if(!fi.isFile())
    {
        if(!QFile::copy(QString("assets:/%1").arg(filename), filename))
        {
            qCritical() << "copy fail:" << filename;
            QMessageBox::critical(nullptr,"错误",QString("copy %1 fail!").arg(filename));
            return false;
        }

        if(QFile::setPermissions(filename, permissionSpec))
            qDebug() << "setPermissions success:" << filename;
        else
        {
            qCritical() << "setPermissions fail:" << filename;
            QMessageBox::warning(nullptr,"警告",QString("setPermissions %1 fail!").arg(filename));
            return false;
        }
    }
    return true;
}


void customMessageHandler(QtMsgType type, const QMessageLogContext &context, const QString &msg)
{
    static QMutex mutex;
    mutex.lock();

    QString text;

    switch(type)
    {
    case QtDebugMsg:
        text = QString("Debug:");
        break;

    case QtWarningMsg:
        text = QString("Warning:");
        break;

    case QtCriticalMsg:
        text = QString("Critical:");
        break;

    case QtFatalMsg:
        text = QString("Fatal:");
        break;

    default:
        text = QString("Unkown:");
        break;
    }

    QString context_info = QString("File:(%1) Line:(%2)").arg(QString(context.file)).arg(context.line);
    QString current_date_time = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss ddd");
    QString current_date = QString("(%1)").arg(current_date_time);
    QString message = QString("%1 %2 %3 %4").arg(text).arg(context_info).arg(msg).arg(current_date);

    QFile file(QString(FIXLOCALPATH_W("log_%1.txt")).arg(QDateTime::currentDateTime().toString("yyyy-MM-dd")));
    file.open(QIODevice::WriteOnly | QIODevice::Append);
    QTextStream text_stream(&file);
    text_stream << message << "\r\n";
    file.flush();
    file.close();

    mutex.unlock();
}



/*
QString("<center><h1>Press: (%1, %2)</h1></center>")
    .arg(QString::number(event->x()),
         QString::number(event->y())));

QString msg;
msg.sprintf("<center><h1>Release: (%d, %d)</h1></center>",
    event->x(), event->y());
*/

QPixmap Ltrans(QPixmap &pix1, int Alpha)
{
    QPixmap temp(pix1.size());
    temp.fill(Qt::transparent);

    QPainter p1(&temp);
    p1.setCompositionMode(QPainter::CompositionMode_Source);
    p1.drawPixmap(0, 0, pix1);
    p1.setCompositionMode(QPainter::CompositionMode_DestinationIn);
    p1.fillRect(temp.rect(), QColor(0, 0, 0, Alpha));
    p1.end();

    return temp;
}



void showHex(char *data,unsigned long length)
{
    QString t,str;
    unsigned long i = 0;
    for(; i < length; i++)
    {
        t.sprintf("0x%x(%c),",*(data + i),*(data + i));
        str += t;
    }
    qDebug() << str;
}

void showHex(QByteArray b)
{
    QString t,str;
    int i = 0;
    for(; i < b.length(); i++)
    {
        t.sprintf("0x%x(%c),",*(b.data() + i),*(b.data() + i));
        str += t;
    }
    qDebug() << str;
}










////////////////////生产者模式类///////////////////
__ProducerData::__ProducerData()
{
    type = 0;
    sender = nullptr;
}
__ProducerData::~__ProducerData()
{
    Release();
}
void __ProducerData::Release()
{}

ProducerModel::ProducerModel(){}
ProducerModel::~ProducerModel()
{
    resetDataList();
}


